package org.apereo.cas.configuration.model.support.wsfed;

import org.apereo.cas.configuration.model.core.util.EncryptionJwtCryptoProperties;
import org.apereo.cas.configuration.model.core.util.EncryptionJwtSigningJwtCryptographyProperties;
import org.apereo.cas.configuration.model.core.util.SigningJwtCryptoProperties;
import org.apereo.cas.configuration.support.DurationCapable;
import org.apereo.cas.configuration.support.RequiresModule;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * This is {@link WsFederationSecurityTokenServiceProperties}.
 *
 * @author Misagh Moayyed
 * @since 6.4.0
 */
@Getter
@Setter
@Accessors(chain = true)
@RequiresModule(name = "cas-server-support-ws-sts")
public class WsFederationSecurityTokenServiceProperties implements Serializable {

    @Serial
    private static final long serialVersionUID = -1155140161252595793L;

    /**
     * When generating a SAML token, indicates the subject name-id format to use.
     * Accepted values are:
     * <ul>
     *     <li>unspecified</li>
     *     <li>email</li>
     *     <li>transient</li>
     *     <li>persistent</li>
     *     <li>entity</li>
     * </ul>
     */
    private String subjectNameIdFormat = "unspecified";

    /**
     * When generating a SAML token, indicates the subject name-id qualifier to use.
     */
    private String subjectNameQualifier = "http://cxf.apache.org/sts";

    /**
     * Set whether the provided token will be signed or not. Default is true.
     */
    private boolean signTokens = true;

    /**
     * Set whether client lifetime is accepted.
     */
    private boolean conditionsAcceptClientLifetime = true;

    /**
     * If requested lifetime exceeds shall it fail (default)
     * or overwrite with maximum lifetime.
     */
    private boolean conditionsFailLifetimeExceedance;

    /**
     * Get how long (in seconds) a client-supplied Created Element is allowed to be in the future.
     * The default is 60 seconds to avoid common problems relating to clock skew.
     */
    @DurationCapable
    private String conditionsFutureTimeToLive = "PT60S";

    /**
     * Set the default lifetime in seconds for issued SAML tokens.
     */
    @DurationCapable
    private String conditionsLifetime = "PT30M";

    /**
     * Set the maximum lifetime in seconds for issued SAML tokens.
     */
    @DurationCapable
    private String conditionsMaxLifetime = "PT12H";

    /**
     * Whether tokens generated by STS should encrypted.
     */
    private boolean encryptTokens = true;

    /**
     * Keystore path used to sign tokens.
     */
    private String signingKeystoreFile;

    /**
     * Keystore password used to sign tokens.
     */
    private String signingKeystorePassword;

    /**
     * Keystore path used to encrypt tokens.
     */
    private String encryptionKeystoreFile;

    /**
     * Keystore password used to encrypt tokens.
     */
    private String encryptionKeystorePassword;

    /**
     * Crypto settings used to secure calls between the idp and the sts.
     */
    @NestedConfigurationProperty
    private EncryptionJwtSigningJwtCryptographyProperties crypto = new EncryptionJwtSigningJwtCryptographyProperties();

    /**
     * Realm definition settings that define this CAS server.
     */
    @NestedConfigurationProperty
    private WsFederationSecurityTokenServiceRealmProperties realm = new WsFederationSecurityTokenServiceRealmProperties();

    /**
     * Collection of fully-qualified claims prefixed with the appropriate
     * namespace that are expected to be released via attribute release policy.
     */
    private List<String> customClaims = new ArrayList<>();

    public WsFederationSecurityTokenServiceProperties() {
        crypto.getEncryption().setKeySize(EncryptionJwtCryptoProperties.DEFAULT_STRINGABLE_ENCRYPTION_KEY_SIZE);
        crypto.getSigning().setKeySize(SigningJwtCryptoProperties.DEFAULT_STRINGABLE_SIGNING_KEY_SIZE);
    }

}
